package com.android.support.lib.universal.sdk.weixin.base;

import java.io.UnsupportedEncodingException;
import java.util.LinkedList;
import java.util.List;

import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONObject;

import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
import android.widget.Toast;

import com.android.support.lib.universal.sdk.weixin.wxapi.Constants;
import com.android.support.lib.universal.sdk.weixin.wxapi.ParamUtil;
import com.android.support.lib.universal.sdk.weixin.wxapi.Util;
import com.android.support.lib.universal.sdk.weixin.wxapi.WeixinManager;
import com.android.support.lib.universal.util.Utilapk;
import com.android.support.lib.universal.util.Utilview;
import com.android.support.lib.universal.view.dialog.CustomProgressDialog;
import com.tencent.mm.sdk.constants.ConstantsAPI;
import com.tencent.mm.sdk.modelbase.BaseReq;
import com.tencent.mm.sdk.modelbase.BaseResp;
import com.tencent.mm.sdk.modelpay.PayReq;
import com.tencent.mm.sdk.openapi.IWXAPI;
import com.tencent.mm.sdk.openapi.IWXAPIEventHandler;
import com.tencent.mm.sdk.openapi.WXAPIFactory;

/**
 * 微信支付（旧接口）; 要求：注册包名.wxapi.WXPayEntryActivity(调起支付对包名和类名没有要求，但是支付回调对包名和类名有要求)
 * 使用说明：注册包名.wxapi.WXPayEntryActivity继承该Activity即可。
 * 
 * @author 彭治铭
 */
public class OldWXPayEntryActivity extends FragmentActivity implements
		IWXAPIEventHandler {
	private IWXAPI api;
	ParamUtil paramUtil = new ParamUtil();
	private static final int WIN_XIN_PAY_FOR_SUCCESS = 0;
	private CustomProgressDialog dialog;
	Handler handler = new Handler() {
		public void handleMessage(android.os.Message msg) {
			switch (msg.what) {
			case WIN_XIN_PAY_FOR_SUCCESS:// 支付成功
				if (((String) msg.obj).equals("0")) {
					WeixinManager.getInstance().onPaySuccess();
					OldWXPayEntryActivity.this.onBackPressed();
					finish();
					api.unregisterApp();
				} else {// 支付失败
					WeixinManager.getInstance().onPayFailed();
					OldWXPayEntryActivity.this.onBackPressed();
					finish();
					api.unregisterApp();
				}
				break;
			}
		};
	};

	@Override
	protected void onStop() {
		// TODO Auto-generated method stub
		super.onStop();
		if (dialog != null) {
			if (dialog.isShowing()) {
				dialog.dismiss();// 关闭进度条
			}
		}
	}

	@Override
	protected void onCreate(Bundle arg0) {
		super.onCreate(arg0);
		dialog = CustomProgressDialog.createDialog(OldWXPayEntryActivity.this);
		dialog.show();
		api = WXAPIFactory.createWXAPI(this, Constants.APP_ID, false);
		Utilapk utilapk = new Utilapk();
		if (utilapk.isWXAppInstalledAndSupported(api)) {
			api.handleIntent(getIntent(), this);
			new GetAccessTokenTask().execute();
		} else {
			this.finish();
		}
		utilapk = null;
	}

	// 1. 获取AccessToken
	private class GetAccessTokenTask extends
			AsyncTask<Void, Void, GetAccessTokenResult> {

		@Override
		protected void onPostExecute(GetAccessTokenResult result) {
			if (result.localRetCode == LocalRetCode.ERR_OK) {
				GetPrepayIdTask getPrepayId = new GetPrepayIdTask(
						result.accessToken);
				// AccessToken获取成功，统一下单
				getPrepayId.execute();
			} else {
				Toast.makeText(OldWXPayEntryActivity.this,
						"AccessToken获取失败：" + result.localRetCode.name(),
						Toast.LENGTH_LONG).show();
			}
		}

		@Override
		protected GetAccessTokenResult doInBackground(Void... params) {
			GetAccessTokenResult result = new GetAccessTokenResult();
			String url = String
					.format("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s",
							Constants.APP_ID, Constants.APP_SECRET);
			byte[] buf = Util.httpGet(url);
			if (buf == null || buf.length == 0) {
				result.localRetCode = LocalRetCode.ERR_HTTP;
				return result;
			}
			String content = new String(buf);
			// 对AccessToken数据进行解析
			result.parseFrom(content);
			return result;
		}
	}

	// 2. 对AccessToken数据进行解析
	private static class GetAccessTokenResult {
		private static final String TAG = "MicroMsg.SDKSample.PayActivity.GetAccessTokenResult";
		public LocalRetCode localRetCode = LocalRetCode.ERR_OTHER;
		public String accessToken;
		@SuppressWarnings("unused")
		public int expiresIn;
		@SuppressWarnings("unused")
		public int errCode;
		@SuppressWarnings("unused")
		public String errMsg;

		public void parseFrom(String content) {
			if (content == null || content.length() <= 0) {
				localRetCode = LocalRetCode.ERR_JSON;
				return;
			}
			try {
				JSONObject json = new JSONObject(content);
				if (json.has("access_token")) {
					accessToken = json.getString("access_token");
					expiresIn = json.getInt("expires_in");
					localRetCode = LocalRetCode.ERR_OK;
				} else {
					errCode = json.getInt("errcode");
					errMsg = json.getString("errmsg");
					localRetCode = LocalRetCode.ERR_JSON;
				}
			} catch (Exception e) {
				localRetCode = LocalRetCode.ERR_JSON;
			}
		}
	}

	private static enum LocalRetCode {
		ERR_OK, ERR_HTTP, ERR_JSON, ERR_OTHER
	}

	// 3.统一下单，获取预支付订单
	private class GetPrepayIdTask extends
			AsyncTask<Void, Void, GetPrepayIdResult> {
		private String accessToken;

		public GetPrepayIdTask(String accessToken) {
			this.accessToken = accessToken;
		}

		@Override
		protected void onPostExecute(GetPrepayIdResult result) {

			if (result.localRetCode == LocalRetCode.ERR_OK) {
				// 下单成功，正式调用微信支付接口
				sendPayReq(result);
			} else {
				Toast.makeText(OldWXPayEntryActivity.this,
						"统一下单失败：" + result.localRetCode.name(),
						Toast.LENGTH_LONG).show();
				OldWXPayEntryActivity.this.finish();
			}
		}

		@Override
		protected void onCancelled() {
			super.onCancelled();
		}

		@Override
		protected GetPrepayIdResult doInBackground(Void... params) {
			String url = String.format(
					"https://api.weixin.qq.com/pay/genprepay?access_token=%s",
					accessToken);// 统一下单，预支付订单
			String entity = paramUtil.genProductArgs_Unifiedorder(
					OldWXPayEntryActivity.this, "APP");
			try {
				entity = new String(entity.getBytes(), "ISO8859-1");// 微信服务器是ISO8859-1的格式。
			} catch (UnsupportedEncodingException e) {
			}
			GetPrepayIdResult result = new GetPrepayIdResult();
			String content = Util.httpPost(url, entity);
			// Log.e("test", "旧接口统一下单数据：" + content);
			if (content == null || content.length() == 0) {
				result.localRetCode = LocalRetCode.ERR_HTTP;
				return result;
			}
			// 对预下单数据进行解析
			result.parseFrom(content);
			return result;
		}
	}

	// 4.解析预下单数据
	private static class GetPrepayIdResult {

		private static final String TAG = "MicroMsg.SDKSample.PayActivity.GetPrepayIdResult";
		public LocalRetCode localRetCode = LocalRetCode.ERR_OTHER;
		public String prepayId;
		@SuppressWarnings("unused")
		public int errCode;
		@SuppressWarnings("unused")
		public String errMsg;

		public void parseFrom(String content) {
			if (content == null || content.length() <= 0) {
				localRetCode = LocalRetCode.ERR_JSON;
				return;
			}
			try {
				JSONObject json = new JSONObject(content);
				if (json.has("prepayid")) {
					prepayId = json.getString("prepayid");
					localRetCode = LocalRetCode.ERR_OK;
				} else {
					localRetCode = LocalRetCode.ERR_JSON;
				}
				errCode = json.getInt("errcode");
				errMsg = json.getString("errmsg");
			} catch (Exception e) {
				localRetCode = LocalRetCode.ERR_JSON;
			}
		}
	}

	// 5.微信返回信息，开始正式调用微信直接接口。
	private void sendPayReq(GetPrepayIdResult result) {

		PayReq req = new PayReq();
		req.appId = Constants.APP_ID;
		req.partnerId = Constants.PARTNER_ID;
		req.prepayId = result.prepayId;
		req.nonceStr = paramUtil.genNonceStr();// // 随机字符串，不长于32位，必须
		req.timeStamp = String.valueOf(System.currentTimeMillis() / 1000);// 时间戳,必不可少
		req.packageValue = "Sign=WXPay";// "Sign=" +
		// packageValue;暂填写固定值Sign=WXPay

		List<NameValuePair> signParams = new LinkedList<NameValuePair>();
		signParams.add(new BasicNameValuePair("appid", req.appId));
		signParams.add(new BasicNameValuePair("appkey", Constants.APP_KEY));
		signParams.add(new BasicNameValuePair("noncestr", req.nonceStr));
		signParams.add(new BasicNameValuePair("package", req.packageValue));
		signParams.add(new BasicNameValuePair("partnerid", req.partnerId));
		signParams.add(new BasicNameValuePair("prepayid", req.prepayId));
		signParams.add(new BasicNameValuePair("timestamp", req.timeStamp));
		req.sign = paramUtil.createSign(signParams);
		// 在支付之前，如果应用没有注册到微信，应该先调用IWXMsg.registerApp将应用注册到微信
		api.sendReq(req);
	}

	@Override
	protected void onNewIntent(Intent intent) {
		super.onNewIntent(intent);
		setIntent(intent);
		api.handleIntent(intent, this);
	}

	@Override
	public void onReq(BaseReq arg0) {
	}

	@Override
	public void onResp(BaseResp resp) {
		if (resp.getType() == ConstantsAPI.COMMAND_PAY_BY_WX) {
			handler.sendMessage(handler.obtainMessage(WIN_XIN_PAY_FOR_SUCCESS,
					resp.errCode + ""));
		} else {
			this.finish();
		}
	}
}
